package game.map;

import game.element.actor.Player;
import game.engine.field.Field;
import game.engine.field.GravityField;
import game.engine.field.Wind;
import game.utility.ResourceUtility;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

public class GameMap {

	public static final String PROPERTYFILENAME = "levelList.txt";
	public static final String FIELDLIST = "fieldList.txt";

	private String mapName;
	private List<String> levelFileNames = new ArrayList<>();
	private List<Field> fields = new LinkedList<>();

	int currentLevel = 0;

	public GameMap(String mapName) {
		this.mapName = mapName;
		BufferedReader levelFileNameReader = ResourceUtility.getBufferedReaderFromFile(ResourceUtility.getMapFilePath(mapName, PROPERTYFILENAME));
		try {
			String levelFileName = levelFileNameReader.readLine();
			while (levelFileName != null) {
				levelFileNames.add(levelFileName);
				levelFileName = levelFileNameReader.readLine();
			}
			setFields();
		} catch (IOException e) {
			throw new RuntimeException(e);
		} finally {
			if (levelFileNameReader != null) {
				try {
					levelFileNameReader.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

	public List<Field> getFields() {
		return fields;
	}

	public GameMapLevel getNexLevel(Player player) {
		if (currentLevel == levelFileNames.size()) {
			return null;
		}
		return new GameMapLevel(ResourceUtility.getMapFilePath(mapName, levelFileNames.get(currentLevel++)), player);
	}

	private void setFields() {
		fields.add(GravityField.singleton());
		try {
			HashMap<String, String> fieldInfos = ResourceUtility.readKeysAndValues(new File(ResourceUtility.getMapFilePath(mapName, FIELDLIST)));
			for (Map.Entry<String, String> entry : fieldInfos.entrySet()) {
				switch (entry.getKey()) {
				case (Wind.TYPE):
					fields.add(new Wind(Integer.parseInt(entry.getValue())));
				}
			}
		} catch (IOException e) {
			throw new RuntimeException();
		}
	}

}